﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;

namespace ParkingYunService
{
    public class PublicManage
    {
        /// <summary>
        /// 指定长度字符串 不足补空格
        /// </summary>
        /// <param name="src">字符串</param>
        /// <param name="len">长度</param>
        /// <returns></returns>
        public static String formatTxt(String src, int len)
        {
            return formatTxt(src, len, " ", true);
        }
        /// <summary>
        /// 指定长度字符串 不足后面补充字符串
        /// </summary>
        /// <param name="src">字符串</param>
        /// <param name="len">长度</param>
        /// <param name="addC">补充字符串</param>
        /// <returns></returns>
        public static String formatTxt(String src, int len, String addC)
        {
            return formatTxt(src, len, addC, true);
        }
        /// <summary>
        /// 获取定长随机数
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        public static String getRandom(int len)
        {
            int max = (int)Math.Pow(10.0D, len + 1) - 1;
            Random random = new Random();
            return formatInt(random.Next(max), len);
        }
        /// <summary>
        /// 指定长度 int 不足前面补充0
        /// </summary>
        /// <param name="num"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static String formatInt(int num, int len)
        {
            String str = num.ToString();
            return formatTxt(str, len, "0", false);
        }
        /// <summary>
        /// 获取定长的字符串
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="len">长度</param>
        /// <returns></returns>
        public static String getSubString(String str, int len)
        {
            byte[] bytes = ByteUtil.getBytes(str);
            if (bytes.Length > len)
            {
                byte[] copy = new byte[len];
                Array.Copy(bytes, copy, len);
                return getString(copy);
            }
            return str;
        }
        /// <summary>
        /// 指定长度字符串 不足补充字符串
        /// </summary>
        /// <param name="src">字符串</param>
        /// <param name="len">长度</param>
        /// <param name="addC">补充字符串</param>
        /// <param name="isAppend">true 后面补充 </param>
        /// <returns></returns>
        public static String formatTxt(String src, int len, String addC, bool isAppend)
        {
            if (src == null)
                src = "";
            String str = src;
            int dif_len = len - ByteUtil.getLength(str);
            for (int i = 0; i < dif_len; ++i)
            {
                if (isAppend)
                    str = str + addC;
                else
                {
                    str = addC + str;
                }
            }
            if (Encoding.Default.GetBytes(str).Length > len)
                str = getSubString(str, len);
            return str;
        }
        /// <summary>
        /// byte[]转换成String
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static String getString(byte[] bytes)
        {
            return System.Text.Encoding.Default.GetString(bytes);
        }
        /// <summary>
        /// 校验签名
        /// </summary>
        /// <param name="model">实体</param>
        /// <param name="sign">签名</param>
        /// <returns></returns>
        public static bool CheckSign(object model, string sign)
        {
            SortedDictionary<string, string> signParams = new SortedDictionary<string, string>(StringComparer.Ordinal);
            var keyValueTo = ToMap(model);
            foreach (var p in keyValueTo)
            {
                if (p.Key != "Sign" && p.Key != "Signlen" && p.Key != "Img")
                {
                    signParams[p.Key] = p.Value;
                }
            }
            StringBuilder paramStr = new StringBuilder();
            foreach (var item in signParams)
            {
                if (string.IsNullOrWhiteSpace(item.Value) == false)
                {
                    paramStr.AppendFormat("{0}={1}&", item.Key, item.Value);
                }
            }
            paramStr.AppendFormat("Key={0}", api_secret);
            string computeSign = GetMd5Hash(paramStr.ToString()).ToUpper();
            return string.Equals(sign, computeSign);
        }
        /// <summary>
        /// 生成签名
        /// </summary>
        /// <param name="model">实体</param>
        /// <returns></returns>
        public static string GetSign(object model)
        {
            SortedDictionary<string, string> signParams = new SortedDictionary<string, string>(StringComparer.Ordinal);
            var keyValueTo = ToMap(model);
            foreach (var p in keyValueTo)
            {
                if (p.Key != "Sign" && p.Key != "Signlen" && p.Key != "Img")
                {
                    signParams[p.Key] = p.Value;
                }
            }
            StringBuilder paramStr = new StringBuilder();
            foreach (var item in signParams)
            {
                if (string.IsNullOrWhiteSpace(item.Value) == false)
                {
                    paramStr.AppendFormat("{0}={1}&", item.Key, item.Value);
                }
            }
            paramStr.AppendFormat("Key={0}", api_secret);
            string computeSign = GetMd5Hash(paramStr.ToString()).ToUpper();
            return computeSign;
        }

        /// <summary>  
        /// 将对象属性转换为key-value对  
        /// </summary>  
        /// <param name="o"></param>  
        /// <returns></returns>  
        private static Dictionary<String, String> ToMap(Object o)
        {
            Dictionary<String, String> map = new Dictionary<String, String>();

            Type t = o.GetType();

            PropertyInfo[] pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo p in pi)
            {
                MethodInfo mi = p.GetGetMethod();

                if (mi != null && mi.IsPublic)
                {
                    map.Add(p.Name, mi.Invoke(o, new String[] { }).ToString());
                }
            }

            return map;

        }
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="input">字符串</param>
        /// <returns></returns>
        public static string GetMd5Hash(string input)
        {
            // Create a new instance of the MD5CryptoServiceProvider object.

            MD5 md5Hasher = MD5.Create();

            // Convert the input string to a byte array and compute the hash.

            byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes

            // and create a string.

            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data 

            // and format each one as a hexadecimal string.

            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.

            return sBuilder.ToString();
        }

        public static string api_secret { get; set; }
    }
}
